package service

import (
	"context"
	"errors"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	v1 "go-websocket/api/im/v1"
	"go-websocket/internal/model/entity"
	"go-websocket/utility"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type Client struct {
	UserId int
	User *entity.TxzhUser
	Ws *ghttp.WebSocket
}


//发送消息
func SendMsg(params *v1.TextMsgReq, session *ghttp.Session) (error, int) {

	userId, err := session.Get("userId")

	if err != nil {
		return errors.New("SendMsg-用户数据异常"), 1
	}

	//mongo
	conn := utility.MgConn("default")
	chatListColl := conn.GetColl("txzh_chat_list")

	// 创建查询条件
	//filter := bson.M{"list_id": listID}

	chatData := chatListColl.FindOne(context.TODO(), bson.M{"list_id": params.ListId})

	var chatList bson.M

	err = chatData.Decode(&chatList)//记录直接查到map

	if err != nil {
		return err, 1
	}

	if len(chatList) == 0 {
		return errors.New("没有这条消息，发送失败"), 1
	}

	var typeValue int
	if intValue32, ok := chatList["type"].(int32); ok {
		// 再将 int32 转换为 int
		typeValue = int(intValue32)
	} else {
		return errors.New("系统错误"), 1
	}

	var isNiMing int
	switch typeValue {
		case 0:
			// 使用 filter 作为查询条件计算满足条件的文档数量
			count, err := chatListColl.CountDocuments(context.TODO(), bson.M{"list_id": params.ListId})
			if err != nil {
				// 处理错误
				return err, 1
			}
			// 使用 count，即查询到的文档数量
			if count == 1 {
				return errors.New("你还不是对方的好友，发送消息失败"), 1
			}

		case 1:
			// 创建投影，指定需要返回的字段，其他字段将不会返回
			//projectionChatGroup := bson.M{"is_msg": 1, "main_id": 1} // 这里只返回 "name" 和 "age" 字段，1 表示要返回，0 表示不返回
			var chatGroup bson.M

			chatGroupColl := conn.GetColl("txzh_chat_group")

			chatGroupColl.FindOne(context.TODO(), bson.M{"list_id": params.ListId}, options.FindOne().SetProjection(bson.M{"is_msg": 1, "main_id": 1})).Decode(&chatGroup)


			chatMemberColl := conn.GetColl("txzh_chat_member")

			var chatMember bson.M



			chatMemberColl.FindOne(context.TODO(), bson.M{"list_id": params.ListId, "userId": userId}, options.FindOne().SetProjection(bson.M{"is_admin": 1, "is_msg": 1, "is_niming": 1})).Decode(&chatMember)

			if _, ok := chatMember["is_niming"];ok {
				isNiMing, _ = chatMember["is_niming"].(int)
			}

			if chatMember["is_msg"].(bool) || (chatGroup["is_msg"].(bool) && chatGroup["main_id"].(int) != 456 && chatMember["is_msg"].(int) !=0 ) {
				return errors.New("你被禁言了"), 2
			}

		default:
			return errors.New("未知对话类型"), 3

	}


	//重新创建会话

	var statusValue int
	if statusValue32, ok := chatList["type"].(int32); ok {
		// 再将 int32 转换为 int
		statusValue = int(statusValue32)
	} else {
		return errors.New("系统错误"), 1
	}

	if statusValue != 0 {
		chatList["status"] = 0
		// 构建用于查找文档的筛选器
		filter := bson.M{"list_id": chatList["list_id"], "userId": userId} // 使用 chatList 中的 _id 字段作为筛选条件
		// 构建更新操作
		update := bson.M{"$set": bson.M{"status": chatList["status"]}} // 更新 name 字段为 chatList 中的 name 值

		// 执行更新操作
		updateResult, err := chatListColl.UpdateOne(context.TODO(), filter, update)
		if err != nil {
			// 处理更新出错的情况
			//panic(err.(interface{}))
			return err, 1
		}
		// 检查更新结果
		if updateResult.ModifiedCount == 0 {
			// 表示未修改任何记录
			// 可能 _id 不存在或未匹配到相应的记录
			// 这里根据实际情况进行处理
			g.Log().Error(context.TODO(), "重新创建会话失败", err)
			return errors.New("更改会话失败"), 1
		}/* else {
			// 更新成功

		}*/


	}



	//mongo写入聊天

	chatColl := conn.GetColl("txzh_chat")
	createData := bson.M{
		"list_id": params.ListId,
		"user_id": userId,
		"content_type": params.ContentType,
		"msg_type": 0,
		"content": params.Content,
		"time": time.Now().Unix(),
		"is_niming": isNiMing,
	}
	insertResualt, err := chatColl.InsertOne(context.TODO(), createData)

	if err != nil {

		return err, 1

	}
	//if insertResult == nil {
	//	return errors.New("修改会话失败"), 1
	//}

	//mongo
	//conn = utility.MgConn("default")
	chatMemberColl := conn.GetColl("txzh_chat_member")
	cursor, err := chatMemberColl.Find(context.TODO(), bson.M{"list_id": params.ListId},options.Find().SetProjection(bson.M{"user_id": 1}))


	var results []map[string]interface{}
	for cursor != nil && cursor.Next(context.TODO()) {
		// 创建一个映射来存储单个文档的数据
		var result map[string]interface{}
		err = cursor.Decode(&result)
		if err != nil {
			return err, 1
		}
		results = append(results, result)
	}

	//fmt.Printf("=%v", results)

	//需通知对象
	var user_ids []int

	for _, member := range results {
		if member["user_id"] != userId {
			filter := bson.M{"list_id": params.ListId, "user_id": member["user_id"]}

			// 定义更新操作，使用bson.D表示文档
			update := bson.D{{"$inc", bson.D{{"no_reader_num", 1}}}}

			// 执行更新操作
			_, err := chatListColl.UpdateOne(context.TODO(), filter, update)

			if err != nil{
				return err, 1
			}
			if uidValue, ok := member["user_id"].(int); ok{
				_ = append(user_ids, uidValue)
			}

		}

		//获取userinfo

		userInfo, err := User.GetUserInfo(userId.Int())
		if err != nil {
			return err, 1
		}

		//TODO
		face := userInfo.face

		userClientTmp := Users.Get(userId.Int())

		if userClient, ok := userClientTmp.(Client); ok {

			sendData := g.Map{
				"data": map[string]interface{}{
					"type": 0,
					"msg": map[string]interface{}{
						"id": insertResualt.InsertedID,
						"type": params.ContentType,
						"time": time.Now().Unix(),
						"user_info": map[string]interface{}{
							"uid": userId,
							"name": userInfo.Nickname,
							"face": face,
						},
						"content": params.Content,
						"is_niming": isNiMing,
						"is_disturb": chatList["is_disturb"],
					},
				},
			}

			err := userClient.Ws.WriteJSON(sendData)
			if err != nil {
				return err, 1
			}
		}


	}

	_, err = chatListColl.UpdateOne(context.TODO(), bson.M{"list_id": params.ListId, "user_id": userId}, bson.M{"last_chat_time": time.Now().Unix()})

	if err != nil {
		return err, 1
	}

	//TODO 发送消息后触发的事件



	return nil, 0
}